function varargout = TLFlipflopDlg(action,varargin)

% TL_FLIPFLOP_DLG manages the user interface for TargetLink Flip-Flop blocks
%
% SYNTAX dlgInfo = TLFlipflopDlg('GetDlgInfo');
%   gets dialog info of TargetLink Flip-Flop blocks
%
%   INPUT ARGUMENTS
%   -/-      
%
%   OUTPUT ARGUMENTS
%   dlgInfo     dialog information contains pageNames etc.
%
% SYNTAX [sheetDims, ctrlPos] = TLFlipflopDlg('CtrlPositions', pageName, commonGeom, dlgInfo, sheetDims);
%   calculates the control positions of all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   commonGeom      common geometry data
%   dlgInfo         dialog information contains pageNames etc.
%   sheetDims       dimension of sheet
%
%   OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% SYNTAX dlgdata = TLFlipflopDlg('Create', pageName, dlgfig, dlgdata);
%   creates all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX [dlgdata,bModified] = TLFlipflopDlg('Manage', pageName, dlgfig, dlgdata, pageAction);
%   manages all actions of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageAction      modified control of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%
% SYNTAX dlgdata = TLFlipflopDlg('Update', dlgfig, dlgdata, pageNum);
%   updates all controls of dialog page: <pageNum>
%
%   INPUT ARGUMENTS
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageNum         number of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX TLFlipflopDlg('Apply', dlgfig, dlgdata);
%   writes current blockdata to block and DD
%
%   INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
%   OUTPUT ARGUMENTS
%   - / -


% Author(s): D. Andoleit, T. Pietzsch
% $RCSfile: TLFlipflopDlg.m $
% $ProjectName: e:/ARC/Components/HostSW/SimulinkBlocksets/TLBlocksets/CommonBlockset/CommonBlockset_SimBlocksUI/Sources/MSrc/project.pj $
% $Revision: 1.27 $
% $Date: 2011/05/12 08:08:23MESZ $
%
% Copyright ?2011 dSPACE GmbH. All rights reserved.


switch action

    case 'GetDlgInfo'
        hBlock = varargin{1};
        dlgInfo = tl_get_dlginfodefaults('tlsim');
        titleName = 'xxx Flip-Flop';
        pathinfo = tl_pathinfo(hBlock);
        dlgInfo.title = sprintf('TargetLink %s: %s', titleName, pathinfo.shortDisplayName);
        dlgInfo.pageNames   = {
            'Output & Logging'; ...
            'Documentation'};
        varargout{1} = dlgInfo;
        varargout{2} = get_tlcg_data(hBlock);

    case 'CtrlPositions'
        pageName     = varargin{1};
        commonGeom   = varargin{2};
        sheetDims    = varargin{4};
        switch pageName
            case 'Output & Logging'
                [sheetDims, ctrlPos] = ...
                    FcnCalcOutputControlPositions(commonGeom);

            case 'Documentation'
                bTblBlock = 0;
                bCodeComment = 1;
                [sheetDims, ctrlPos] = TLManageDocCtrls( ...
                    'ctrlpos', commonGeom, sheetDims, bCodeComment, bTblBlock);
        end
        varargout{1} = sheetDims;
        varargout{2} = ctrlPos;

    case 'Create'
        pageName = varargin{1};
        dlgfig   = varargin{2};
        dlgdata  = varargin{3};
        pageNum  = strmatch(pageName, dlgdata.pageNames, 'exact');

        switch pageName
            case 'Output & Logging'
                dlgdata = FcnCreateOutputControls(pageNum, dlgfig, dlgdata);

            case 'Documentation'
                dlgdata = ...
                    TLManageDocCtrls('create', pageNum, dlgfig, dlgdata);
        end
        dlgdata.pageData{pageNum}.ctrlPos = [];
        varargout{1} = dlgdata;

    case 'Manage',
        pageName   = varargin{1};
        dlgfig     = varargin{2};
        dlgdata    = varargin{3};
        pageAction = varargin{4};
        pageNum    = strmatch(pageName,dlgdata.pageNames, 'exact');
        switch pageName
            case 'Output & Logging'
                [dlgdata, bModified] = FcnManageOutputControls( ...
                    pageNum, dlgfig, dlgdata, pageAction);
            case 'Documentation'
                [dlgdata,bModified] = TLManageDocCtrls( ...
                    'callback', pageNum, dlgfig, dlgdata, pageAction);
        end
        varargout{1} = dlgdata;
        varargout{2} = bModified;

    case 'ManageSystemIcons',
        dlgfig     = varargin{1};
        dlgdata    = varargin{2};
        pageAction = varargin{3};
        [dlgdata, bModified] = FcnManageSystemIcons(dlgfig,dlgdata,pageAction);
        varargout{1} = dlgdata;
        varargout{2} = bModified;

    case 'Update'
        dlgfig  = varargin{1};
        dlgdata = varargin{2};
        pageNum = varargin{3};
        pageName = dlgdata.pageNames{pageNum};
        switch pageName
            case 'Output & Logging'
                dlgdata = FcnUpdateOutputControls(dlgdata, dlgfig, pageNum);
            case 'Documentation'
                TLManageDocCtrls('update', pageNum, dlgfig, dlgdata);
        end
        varargout{1} = dlgdata;

    case 'Apply'
        dlgdata  = varargin{2};
        bClose   = varargin{3};
        [dlgdata, bClose] = tl_apply_blockdata(dlgdata, bClose);
        varargout{1} = dlgdata;
        varargout{2} = bClose;

    otherwise
        error(['Invalid action "' action '"']);
end


%-----------------------------------------------------------------------------------------
% FcnManageSystemIcons manage actions of toolbar icons
%
% INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   action      action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageSystemIcons(dlgfig, dlgdata, action) %#ok

bModified = false;
switch action
    
    case 'EditCode'
        % look for associated production code file
        [codefile,blockstr] = get_codefile(dlgdata.model);
        if ~isempty(codefile)
            codeedit(codefile,blockstr);
        end

    case 'ViewCode'
        blockVar{1} = 'output';
        blockVar{2} = 'noutput';
        idx = get(dlgdata.pageData{1}.children.selectPopup,'Value');
        tl_create_links_to_model('ShowComputation',dlgdata.model, blockVar{idx});

    otherwise
        error('Invalid callback');

end % switch(action)


%-----------------------------------------------------------------------------------------
% FcnCalcOutputControlPositions calculates positions for all controls on output page
%
% INPUT ARGUMENTS
%   commonGeom      common geometrie information
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims,ctrlPos] = FcnCalcOutputControlPositions(commonGeom)

% calculate positions of output controls
excludedCtrls = {'allscaling','inheritproperties', 'castoutput', 'width', 'element', 'scaling', 'scalarExp'};
[sheetDims, ctrlPosOutputFrame, colOutputFrame, colDelta, rowDelta] =  ...
    tl_calc_ctrls_positions(commonGeom, excludedCtrls);

% calculate positions of logging controls
excludedCtrls = {'autoscaling', 'plotEdit'};
[sheetDims, ctrlPos] = ...
    TLManageLoggingCtrls('calcCtrls', commonGeom, sheetDims, excludedCtrls);

% merge position structs, shift output controls
fieldNameList = fieldnames(ctrlPosOutputFrame);
fieldNameList = reshape(fieldNameList, 1, length(fieldNameList));
for fieldName = fieldNameList,
    fieldValue = ctrlPosOutputFrame.(char(fieldName));
    ctrlPos.(char(fieldName)) = fieldValue - [0, commonGeom.editHeight+rowDelta, 0 , 0];
end

% adapt box cordinates
ctrlPos.tlcgoptGroupbox(2) = ctrlPos.logplotGroupbox(2) + ctrlPos.logplotGroupbox(4) + commonGeom.textHeight;

strings_and_styles = {
    'Select:',            'text';
    'Initial condition:', 'text';
    'BaseType: ',         'text';
    'Use value of Data Dictionary variable',    'checkbox'};

[selectLabelSize, ...
    initialLabelSize, ...
    baseTypeLabelSize, ...
    useDDValueCheckboxSize] = ...
    ds_get_uicontrol_sizes(commonGeom, strings_and_styles);

% supplement tlcgGroupbox
cy = ctrlPos.descLabel(2) + commonGeom.editHeight + rowDelta;

% select label
cx = colOutputFrame(1);
ctrlPos.selectLabel = [cx cy selectLabelSize];

% select popup
cx = ctrlPos.descEdit(1);
ctrlPos.selectPopup = [cx cy ctrlPos.addressEdit(3:4)];

% baseTypeLabel
ctrlPos.baseTypeLabel(1) = ctrlPos.nameLabel(1);
ctrlPos.baseTypeLabel(2) = ctrlPos.typeLabel(2);
ctrlPos.baseTypeLabel(3) = baseTypeLabelSize(1);

% baseTypeInfo
ctrlPos.baseTypeInfo(1) = ctrlPos.baseTypeLabel(1) + baseTypeLabelSize(1);
ctrlPos.baseTypeInfo(2) = ctrlPos.baseTypeLabel(2);

% define an additional box for initial condition
ctrlPos.initcondGroupbox(1) = ctrlPos.tlcgoptGroupbox(1);
ctrlPos.initcondGroupbox(2) = ctrlPos.tlcgoptGroupbox(2) ...
    + ctrlPos.tlcgoptGroupbox(4) ...
    + commonGeom.textHeight;
ctrlPos.initcondGroupbox(3) = ctrlPos.tlcgoptGroupbox(3);
ctrlPos.initcondGroupbox(4) = ...
      commonGeom.frameBottomEdgeBuffer ...
    + commonGeom.editHeight ...
    + rowDelta ...
    + commonGeom.checkboxHeight ...
    + commonGeom.frameTopEdgeBuffer;

%---------------------------------------
% 2nd row
cy = commonGeom.frameBottomEdgeBuffer;

% use ddv checkbox
cx = colOutputFrame(1) + initialLabelSize(1) + colDelta / 3;
ctrlPos.useDDValueCheckbox = [cx, cy, useDDValueCheckboxSize];

%---------------------------------------
% 1st row
cy = cy + commonGeom.checkboxHeight + rowDelta;

% initial value label
cx = colOutputFrame(1);
ctrlPos.initialLabel = [cx cy initialLabelSize];

% initial value edit field
cx = cx + initialLabelSize(1) + colDelta/3;
controlWidth = colOutputFrame(4) - cx - colDelta/3;
ctrlPos.initialEdit = [cx cy controlWidth commonGeom.editHeight];

width = ctrlPos.tlcgoptGroupbox(3) ...
    + 2 * commonGeom.frameSideEdgeBuffer;

height = ctrlPos.logplotGroupbox(4) ...
    + ctrlPos.tlcgoptGroupbox(4) ...
    + ctrlPos.initcondGroupbox(4) ...
    + 3 * commonGeom.textHeight ...
    + commonGeom.sheetBottomEdgeBuffer;

sheetDims = [width height];


%-----------------------------------------------------------------------------------------
% FcnCreateOutputControls creates the figure window
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateOutputControls(pageNum,dlgfig,dlgdata)

ctrlPos  = dlgdata.pageData{pageNum}.ctrlPos;

% create standard variable controls
dlgdata = TLManageVariableCtrls('create', pageNum, dlgfig, dlgdata);
% no scaling controls

% create logging controls
dlgdata = TLManageLoggingCtrls('create', pageNum, dlgfig, dlgdata);

Children = dlgdata.pageData{pageNum}.children;

% modify panel title
set(dlgdata.pageData{pageNum}.children.tlcgoptGroupbox, 'Title', 'Outputs');

% selection popup
Children.selectLabel = uicontrol( ...
    'Parent',             Children.tlcgoptGroupbox, ...
    'Style',              'text', ...
    'String',             'Select:', ...
    'Position',           ctrlPos.selectLabel);

Children.selectPopup = uicontrol( ...
    'Parent',             Children.tlcgoptGroupbox, ...
    'Style',              'Popupmenu', ...
    'BackgroundColor',    'w', ...
    'String',             {'output'; 'noutput'}, ...
    'Value',              1, ...
    'Position',           ctrlPos.selectPopup);

% initial value groupbox
Children.initcondGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Initial condition'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.initcondGroupbox);

% output initial value controls
Children.initialLabel = uicontrol( ...
    'Parent',             Children.initcondGroupbox, ...
    'Style',              'text', ...
    'String',             'Initial condition:', ...
    'Position',           ctrlPos.initialLabel);

Children.initialEdit = uicontrol( ...
    'Parent',             Children.initcondGroupbox, ...
    'Style',              'edit', ...
    'Position',           ctrlPos.initialEdit);

Children.useDDValueCheckbox = uicontrol( ...
    'Parent',             Children.initcondGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Use value of Data Dictionary variable', ...
    'Position',           ctrlPos.useDDValueCheckbox);

dlgdata.pageData{pageNum}.children = Children;


%-----------------------------------------------------------------------------------------
% FcnManageOutputControls manage control actions of output page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageOutputControls(pageNum,dlgfig,dlgdata,pageAction)

Children = dlgdata.pageData{pageNum}.children;
switch pageAction
    
    case 'selectPopup'
        bModified = true;

    case 'initialEdit'
        initialStr = get(Children.initialEdit, 'String');
        if ~isempty(initialStr)
            if strcmp(initialStr, 'ddv')
                if isempty(dlgdata.data.output.variable)
                    beep;
                else
                    dlgdata.data.output.initial = ['ddv(''', dlgdata.data.output.variable, ''')'];
                    dlgdata.data.output.useddvariablevalue = true;
                end
            else
                dlgdata.data.output.initial = initialStr;
            end
        else
            beep;
        end
        bModified = true;

    case 'useDDValueCheckbox'
        if get(Children.useDDValueCheckbox, 'Value')
            dlgdata.data.output.initial = ['ddv(''', dlgdata.data.output.variable, ''')'];
            dlgdata.data.output.useddvariablevalue = true;
        else
            dlgdata.data.output.useddvariablevalue = false;
        end
        bModified = true;

    case {'logPopup', 'plotCheckbox', 'samplesEdit'}
        selectIdx = get(Children.selectPopup, 'value');
        logVars = {'logdata', 'nlogdata'};
        [dlgdata, bModified] = ...
            TLManageLoggingCtrls('manage', pageNum, dlgdata, pageAction, logVars{selectIdx});

    otherwise
        fieldIdx = get(Children.selectPopup, 'Value');
        vars = {'output', 'noutput'};
        field = vars{fieldIdx};
        [dlgdata, bModified] = TLManageVariableCtrls( ...
            'manage', pageNum, dlgfig, dlgdata, pageAction, field);
        
end


%--------------------------------------------------------------------------
% FcnUpdateOutputControls updates the output controls
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateOutputControls(dlgdata,dlgfig,pageNum)

Children = dlgdata.pageData{pageNum}.children;

% status of selection popup
selectIdx = get(Children.selectPopup, 'Value');
switch selectIdx
    case 1
        field = 'output';
        logfield = 'logdata'; 
    case 2
        field = 'noutput';
        logfield = 'nlogdata'; 
end

% default control status for controls
initialEditCtrlStatus = struct('enable', 'on', 'string', '');
baseTypeLabelCtrlStatus = struct('enable', 'on', 'string', '');
baseTypeInfoCtrlStatus = struct('enable', 'on', 'string', '');

% invoke standard update methods
dlgdata = TLManageVariableCtrls('update', pageNum, dlgdata, field);
dlgdata = TLManageLoggingCtrls('update', pageNum, dlgdata, logfield, field);

% status of ddv checkbox
useDDValueCheckboxCtrlStatus.enable = flag2str(selectIdx == 1 && ~isempty(dlgdata.data.output.initial));
useDDValueCheckboxCtrlStatus.value = dlgdata.data.output.useddvariablevalue;

% status of initial value field
initialEditCtrlStatus.string = dlgdata.data.output.initial;
if selectIdx == 2
    initialEditCtrlStatus.enable = 'off';
elseif dlgdata.data.output.useddvariablevalue
    initialEditCtrlStatus.enable = 'inactive';
end

% handle base type
typedef = dlgdata.data.(field).type;
[bExist, hTypedef] = dsdd('Exist', ['/Pool/Typedefs/' typedef]);
UserData = get(Children.typeEdit, 'UserData');
typeEditCtrlStatus = UserData.ctrlStatus;
if bExist && ds_isa(hTypedef, 'booltype')
    [baseType, errCode] = dsdd('GetBaseType', hTypedef);
    if ~dsdd_check_msg(errCode)
        baseTypeInfo = dsdd('GetBaseTypeRename', ['/Pool/Typedefs/' baseType]);
        baseTypeLabelCtrlStatus.string = 'Base type:';
        if isempty(baseTypeInfo)
            baseTypeInfo = baseType;
        end
        baseTypeInfoCtrlStatus.string = baseTypeInfo;
    end
else
    typeEditCtrlStatus.iserror = 1;
end

% write control status of extra controls to the control
extraCtrlsList = {
    'initialEdit', ...
    'baseTypeInfo', ...
    'baseTypeLabel', ...
    'useDDValueCheckbox'};
ctrlsList = [extraCtrlsList {'typeEdit'}];
for ctrlsNo = 1:length(ctrlsList)
    ctrl = Children.(ctrlsList{ctrlsNo});
    UserData = get(ctrl, 'UserData');
    UserData.ctrlStatus = eval([ctrlsList{ctrlsNo} 'CtrlStatus']);
    set(ctrl, 'UserData', UserData);
end

% set controls
TLManageLoggingCtrls('setCtrls',pageNum, dlgfig, dlgdata);
TLManageVariableCtrls('setCtrls', pageNum, dlgfig, dlgdata);
TLSetCtrlsStatus(dlgfig, Children, extraCtrlsList);
